//
//  BridgeScrollConfiguration.swift
//  BridgeScrollView
//
//  Created by zjkj on 2024/8/5.
//

import SwiftUI

@available(iOS 14.0, *)
public class BridgeScrollConfiguration: ObservableObject {
    
    /// 当前滑动状态
    public enum ScrollType: Equatable {
        /// 静止
        case `static`
        /// 滑动中，滑动方向
        case scrolling(Direction)
    }
    
    /// 滑动方向
    public struct Direction: OptionSet {
        public let rawValue: Int
        
        public init(rawValue: Int) {
            self.rawValue = rawValue
        }
        
        /// 静止
        static public let `static` = Direction(rawValue: 1 << 0)
        /// 左滑
        static public let left = Direction(rawValue: 1 << 1)
        /// 右滑
        static public let right = Direction(rawValue: 1 << 2)
        /// 上滑
        static public let top = Direction(rawValue: 1 << 3)
        /// 下滑
        static public let bottom = Direction(rawValue: 1 << 4)
        /// 左上滑
        static public let leftTop: Direction = [.left, .top]
        /// 左下滑
        static public let leftbottom: Direction = [.left, .bottom]
        /// 右上滑
        static public let rightTop: Direction = [.right, .top]
        /// 又下滑
        static public let rightBottom: Direction = [.right, .bottom]

    }
    
    /// 是否分页滑动
    @Published public var isPagingEnable: Bool = false
    /// 是否有回弹效果
    @Published public var isBounces: Bool = true
    /// 当前的偏移量
    @Published public private(set) var contentOffset: CGPoint = .zero
    /// 当前的ContentSize
    @Published public private(set) var contentSize: CGSize = .zero
    /// 滑动状态
    @Published public private(set) var scrollType: ScrollType = .static
    /// 是否正在滑动
    @Published public private(set) var isScrolling: Bool = false
    /// 是否处于脱手滚动状态
    @Published public private(set) var isDecelerating: Bool = false
    /// 是否正在拖动
    @Published public private(set) var isDragging: Bool = false
    /// 当前是否在顶部
    @Published public private(set) var isTop: Bool = true
    /// 当前是否在底部
    @Published public private(set) var isBottom: Bool = false
    /// 是否正在缩放
    @Published public private(set) var isZooming: Bool = false
    /// 当前的缩放比例
    @Published public private(set) var zoomLevel: CGFloat = 1
    /// 是否是用户拖动引起的滚动
    @Published public private(set) var isUserScroll: Bool = false
    /// ContSize > height
    @Published public private(set) var isFull: Bool = false
    /// SwiftUI 滚动代理
    public var scrollViewProxy: ScrollViewProxy?
    /// UIKit 滑动到指定位置
    public var scrollToOffset: ((_ offset: CGPoint, _ animated: Bool) -> ())?
    /// 内边距，这个用于判断是否在顶部和在底部的的判断范围
    var ignoreInsets: UIEdgeInsets = .zero
    /// 主线程
    let mainQueue = DispatchQueue.main
    
    /// 配置初始化方法
    /// - Parameters:
    ///   - isPagingEnable: 是否分页
    ///   - isBounces: 是否有回弹效果
    ///   - ignoreInsets: 顶部和底部判断忽略范围
    public init(isPagingEnable: Bool = false,
                isBounces: Bool = true,
                ignoreInsets: UIEdgeInsets = .zero) {
        self.isPagingEnable = isPagingEnable
        self.isBounces = isBounces
        self.ignoreInsets = ignoreInsets
    }
}

extension BridgeScrollConfiguration {
    /// 更新ContentSize
    /// - Parameter size: ContentSize
    func updateContentOffset(_ offset: CGPoint) {
        mainQueue.async {[weak self] in
            self?.contentOffset = offset
        }
    }
    
    /// 更新ContentSize
    /// - Parameter size: ContentSize
    func updateContentSize(_ size: CGSize) {
        mainQueue.async {[weak self] in
            self?.contentSize = size
        }
    }
    
    /// 更新是否正在滚动
    /// - Parameter isScroll: 是否正在滚动
    func updateIsScrolling(_ isScroll: Bool) {
        mainQueue.async {[weak self] in
            self?.isScrolling = isScroll
        }
    }
    
    /// 更新是否正在执行惯性滚动效果
    /// - Parameter decelerating: 惯性滚动
    func updateIsDecelerating(_ decelerating: Bool) {
        mainQueue.async {[weak self] in
            self?.isDecelerating = decelerating
        }
    }
    
    /// 更新是否正在拖拽
    /// - Parameter isDrag: 拖拽
    func updateIsDrag(_ isDrag: Bool) {
        mainQueue.async {[weak self] in
            self?.isDragging = isDrag
        }
    }
    
    /// 更新是否在顶部
    /// - Parameter atTop: 是否在顶部
    func updateIsTop(_ atTop: Bool) {
        mainQueue.async {[weak self] in
            self?.isTop = atTop
        }
    }
    
    /// 更新是否在底部
    /// - Parameter atBottom: 是否在底部
    func updateIsBottom(_ atBottom: Bool) {
        mainQueue.async {[weak self] in
            self?.isBottom = atBottom
        }
    }
    
    /// 更新当前是否正在缩放
    /// - Parameter isZoom: 缩放
    func updateIsZooming(_ isZoom: Bool) {
        mainQueue.async {[weak self] in
            self?.isZooming = isZoom
        }
    }
    
    /// 更新当前缩放倍数
    /// - Parameter level: 缩放倍数
    func updateZoomLevel(_ level: CGFloat) {
        mainQueue.async {[weak self] in
            self?.zoomLevel = level
        }
    }
    
    /// 更新是否用户拖动
    /// - Parameter userScroll: 用户拖动
    func updateIsUserScroll(_ userScroll: Bool) {
        mainQueue.async {[weak self] in
            self?.isUserScroll = userScroll
        }
    }
    
    /// 更新是否满屏
    /// - Parameter userScroll: 用户拖动
    func updateIsFull(_ full: Bool) {
        mainQueue.async {[weak self] in
            self?.isFull = full
        }
    }
    
    /// 更新当前滚动状态
    /// - Parameter type: 滚动状态
    func updateScrollType(_ type: Direction) {
        mainQueue.async {[weak self] in
            self?.scrollType = .scrolling(type)
        }
    }
}
